package com.hkyp.ss.course.provider.impl;

import com.hkyp.ss.course.apis.NavigationItemService;
import com.hkyp.ss.course.apis.dto.request.NavigationItemDTO;
import com.hkyp.ss.course.apis.dto.response.NavigationItemVO;
import com.hkyp.ss.course.apis.exception.ServiceException;
import com.hkyp.ss.course.apis.exception.UnacceptableException;
import com.hkyp.ss.course.apis.utils.BeanMapper;
import com.hkyp.ss.course.provider.model.NavigationItem;
import com.hkyp.ss.course.provider.repository.NaviItemRepository;
import org.apache.dubbo.config.annotation.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/****
 *
 导航栏逻辑

 code

 x%10000==0        一级导航栏


 x%100==0 && x%10000!=0   二级导航栏


 x%1==0 &&  x%100!=0   三级导航栏


 一级导航栏从属判断依据：
 x < y < x+10000 && y%100 == 0



 二级导航栏从属判断判断依据：
 x < y < x+100

 010000
 019999



 010100
 010199


 010102
 60000

 [

 ]
 { 1000000
 x%1000000
 01010101

 }

 *
 */
@Service(version = "1.0")
@Transactional(rollbackFor = Exception.class)
public class NavigationItemServiceImpl implements NavigationItemService {

    private static Logger logger = LoggerFactory.getLogger(NavigationItemServiceImpl.class);

    @Autowired
    private NaviItemRepository naviItemRepository;

    @Override
    public void addNavigationItem(NavigationItemDTO navigationItemDTO){
        NavigationItem navigationItem = new NavigationItem();

        Long parentCode = navigationItemDTO.getParentCode();

        Long newCode = 0L;
        //增加一级导航栏
        if(navigationItemDTO.getGrade() == 1){

            boolean flag = naviItemRepository.existsByValueAndGrade(navigationItemDTO.getValue(),1);
            if(flag){
                throw new UnacceptableException("该导航栏名称已存在");
            }
            Integer maxCode = naviItemRepository.getMaxCode();

            newCode = maxCode-(maxCode%10000)+10000L;

        //增加二级导航栏
        }else if(navigationItemDTO.getGrade() == 2){

            //判断表中是否存在同名二级导航栏
            boolean flag = naviItemRepository.existsByValueAndGrade(navigationItemDTO.getValue(),2);
            if(flag){
                throw new UnacceptableException("该导航栏名称已存在");
            }

            Long pCode = navigationItemDTO.getParentCode();
            if(pCode == null){
                throw new UnacceptableException("父code不能为null");
            }
            if(pCode%10000 != 0){
                throw new UnacceptableException("父code格式不对");
            }
            //获得该父节点下最大子节点
            Integer MaxChild = naviItemRepository.getMaxCodeFromParent(pCode,pCode+10000);
            if(MaxChild != null){
                newCode = MaxChild-(MaxChild%100)+100L;
            // 如果取出的最大子节点为空，说明还没有加入过子节点
            }else {
                newCode = parentCode+100;
            }


        }else if(navigationItemDTO.getGrade() == 3){

            Long pCode = navigationItemDTO.getParentCode();
            if(pCode == null){
                throw new UnacceptableException("父code不能为null");
            }
            if(pCode%100 != 0 || pCode%10000 ==0){
                throw new UnacceptableException("父code格式不对");
            }

            boolean flag = naviItemRepository
                    .existsByValueAndCodeGreaterThanAndCodeLessThan
                            (navigationItemDTO.getValue(),pCode,pCode+100);
            if(flag){
                throw new UnacceptableException("此父级下，该导航栏名称已存在");
            }

            //获得该父节点下最大子节点
            Integer MaxChild = naviItemRepository.getMaxCodeFromParent(pCode,pCode+100);
            logger.info("取到的指定范围内的最大节点：{}",MaxChild);
            if(MaxChild != null){
                newCode = MaxChild+1L;
            // 如果取出的最大子节点为空，说明还没有加入过子节点
            }else {
                newCode = parentCode+1;
            }
        }

        if(newCode == 0){
            throw new ServiceException("遇到了异常");
        }

        navigationItem.setCode(newCode);
        navigationItem.setCreateAt(System.currentTimeMillis());
        navigationItem.setGrade(navigationItemDTO.getGrade());
        navigationItem.setValue(navigationItemDTO.getValue());

        logger.info("即将插入数据库的对象：{}",navigationItem);

        naviItemRepository.save(navigationItem);

    }

    @Override
    @Transactional(readOnly = true)
    public List<NavigationItemVO> getAllNavigationItemList() {

        List<NavigationItem> allNaviItemList = naviItemRepository.findAll();
        List<NavigationItemVO> navigationItemVOS = BeanMapper.mapList(allNaviItemList, NavigationItemVO.class);

        return navigationItemVOS;
    }

    @Override
    @Transactional(readOnly = true)
    public List<NavigationItemVO> getNavigationItemsByCodes(List<Long> codes) {

        List<NavigationItem> allNaviItemList = naviItemRepository.findAllByCodeIn(codes);
        List<NavigationItemVO> navigationItemVOS = BeanMapper.mapList(allNaviItemList, NavigationItemVO.class);

        return navigationItemVOS;
    }


}
